package com.jacky.demo;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.jacky.demo.util.StorageUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Administrator on 2017-06-27.
 */

public class ErrorActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String text = getIntent().getStringExtra(Intent.EXTRA_TEXT);

        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        TextView view = new TextView(this);
        view.setText(text);
        view.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.ic_error_activity,0,0);
        layout.addView(view);

        Button button = new Button(this);
        button.setText("重启应用");
        button.setOnClickListener(this);
        layout.addView(button);

        ScrollView root = new ScrollView(this);
        root.addView(layout);
        setContentView(root);
    }

    @Override
    public void onClick(View view) {
        Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    }

    public static void setDefaultUncaughtExceptionHandler(Context context) {
        CrashHandler handler = new CrashHandler(context);
        Thread.setDefaultUncaughtExceptionHandler(handler);
    }

    static class CrashHandler implements Thread.UncaughtExceptionHandler {

        private static final int HE_DEFAULT = 0;
        private static final int HE_FILE = 1;
        private static final int HE_ACTIVITY = 2;

        private Context mContext;
        private final Thread.UncaughtExceptionHandler mExceptionHandler;

        private CrashHandler(Context context) {
            mContext = context;
            mExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        }

        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            Log.e("crash", "", ex);
            if(mExceptionHandler!= null && !handleException(ex, HE_ACTIVITY)) {
                mExceptionHandler.uncaughtException(thread, ex);
            } else {
//            android.os.Process.killProcess(android.os.Process.myPid());
//            System.exit(1);
                try {
                    forceStop();
                } catch (IOException e) {
                    Log.e("crash", "", e);
                }
            }
        }

        private boolean handleException(Throwable ex, int he) {
            switch (he) {
                case HE_FILE :
                    final String string = saveToFile(ex);
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Looper.prepare();
                            Toast.makeText(mContext,
                                    "错误日志存放在：" + string, Toast.LENGTH_LONG).show();
                            Looper.loop();
                        }
                    }).start();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    break;
                case HE_ACTIVITY :
                    String log = Log.getStackTraceString(ex);
                    Intent intent = new Intent(mContext, ErrorActivity.class);
                    intent.putExtra(Intent.EXTRA_TEXT, log);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
                    PendingIntent pIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
                    AlarmManager manager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
                    manager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pIntent);
                    break;
                case HE_DEFAULT :
                default:
                    return false;
            }
            return true;
        }

        private String saveToFile(Throwable ex) {
            File mSaveDir = StorageUtil.getLogDir();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.SIMPLIFIED_CHINESE);
            String filename = format.format(new Date());

            File file = new File(mSaveDir,filename + ".txt");
            FileOutputStream stream = null;
            try {
                stream = new FileOutputStream(file);
                String log = Log.getStackTraceString(ex);
                stream.write(log.getBytes());
            } catch (Exception e) {
                Log.e("crash", "", e);
            } finally {
                if(stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                    }
                }
            }
            return file.getAbsolutePath();
        }

        private void forceStop() throws IOException {
            Runtime runtime = Runtime.getRuntime();
            String cmd = "kill -9 " + android.os.Process.myPid();
            Log.e("crash", cmd);
            runtime.exec(cmd);
        }
    }
}
